/*
 ============================================================================
 Name		: VoiceEngine.cpp
 Author	  : William Zhang
 Version	 : 1.0
 Copyright   : all rights reserved.
 Description : CVoiceEngine implementation
 ============================================================================
 */

#include "VoiceEngine.h"
#include "Utils.h"

CVoiceEngine::CVoiceEngine()
	{
	// No implementation required
	}

CVoiceEngine::~CVoiceEngine()
	{
	}

CVoiceEngine* CVoiceEngine::NewLC()
	{
	CVoiceEngine* self = new (ELeave) CVoiceEngine();
	CleanupStack::PushL(self);
	self->ConstructL();
	return self;
	}

CVoiceEngine* CVoiceEngine::NewL()
	{
	CVoiceEngine* self = CVoiceEngine::NewLC();
	CleanupStack::Pop(); // self;
	return self;
	}

void CVoiceEngine::ConstructL()
	{

	const TVersion ver(1,0,0);
	
	TInt err = CVoIPUtilityFactory::CreateFactory(iFactory);
	if(err == KErrNone)
		{
    err = iFactory->CreateDownlinkStream(ver,
                                         CVoIPUtilityFactory::EVoIPCall,
                                         iVoiceDnlink);
    if (err != KErrNone)
        {
        CUtils::ShowMsg(_L("Create Dn err"),err);
        }
    iFactory->CreateBuffer(iRecvVoiceBuf, CVoIPDataBuffer::EStandard);
    
    err = iFactory->CreateUplinkStream(ver,
                                       CVoIPUtilityFactory::EVoIPCall,
                                       iVoiceUplink);
    if (err != KErrNone)
        {
        CUtils::ShowMsg(_L("Create Up err"),err);
        }
    iFactory->CreateBuffer(iSendVoiceBuf, CVoIPDataBuffer::EStandard);
//    if (iVoiceDnlink)
//        {
//        err = iFactory->CreateDTMFTonePlayer(iDTMFTonePlayerDn);
//        if (err != KErrNone)
//            {
//            DisplayText(_L("Error CreateDTMFTonePlayerDNL"), KRgbRed, err);
//            }
//        }
//
//    if (iVoiceUplink)
//        {
//        err = iFactory->CreateDTMFTonePlayer(iDTMFTonePlayerUp);
//        if (err != KErrNone)
//            {
//            DisplayText(_L("Error CreateDTMFTonePlayerUPL"), KRgbRed, err);
//            }
//        }

		}
	}


void CVoiceEngine::Init()
	{
	
	InitDn();
	
	InitUp();
	
	}

void CVoiceEngine::InitDn()
	{
	//set format and call Open()
	SetDnFormat(EAMR_NB);
	
	}

void CVoiceEngine::SetDnFormat(TVoIPCodecFormat aFormat)
	{
    TInt err = iVoiceDnlink->SetFormat(aFormat, iDnFormat);

    if (err != KErrNone)
        {
        delete iDnFormat;
        CUtils::ShowMsg((_L("DNL Codec Setting Failed"), err);
        return;
        }

    switch (aFormat)
        {
        case EAMR_NB:
            {
            err = iDnFormat->SetObserver(*this);
//            CUtils::ShowMsg((_L("AMR-NB DNL Codec Set"), err);
            break;
            }
        default:
            {
            err = KErrNotSupported;
            break;
            }
        }

    if (err == KErrNone)
        {
        //iDnLinkCodec = aCodecFormat;

        // optional automatic open
        err = iVoiceDnlink->Open(*this);
        if(err != KErrNone)
        	{
			CUtils::ShowMsg(_L("Open Dnlink err"),err);
        	}
        }	
	}

void CVoiceEngine::InitUp()
	{
	
	}


void CVoiceEngine::SetUpFormat(TVoIPCodecFormat aFormat)
	{
    TInt err = iVoiceDnlink->SetFormat(aFormat, iUpFormat);

    if (err != KErrNone)
        {
        delete iUpFormat;
        CUtils::ShowMsg((_L("DNL Codec Setting Failed"), err);
        return;
        }

    switch (aFormat)
        {
        case EAMR_NB:
            {
            err = iUpFormat->SetObserver(*this);
//            CUtils::ShowMsg((_L("AMR-NB DNL Codec Set"), err);
            break;
            }
        default:
            {
            err = KErrNotSupported;
            break;
            }
        }

    if (err == KErrNone)
        {
        //iDnLinkCodec = aCodecFormat;

        // optional automatic open
        err = iVoiceUplink->Open(*this);
        if(err != KErrNone)
        	{
			CUtils::ShowMsg(_L("Open Dnlink err"),err);
        	}
        }	
	}

//========================MVoIPDownlinkObserver===========================
//
// Callback by VoIP Audio Service server, call BufferFilled() here
//
void CVoiceEngine::FillBuffer(const CVoIPAudioDownlinkStream& aSrc,
        CVoIPDataBuffer* aBuffer)
	{
	// call BufferFilled() here
	
	}

void CVoiceEngine::Event(const CVoIPAudioDownlinkStream& aSrc,
                       TInt aEventType,
                       TInt aError)
	{
	
	switch(aEventType)
		{
		case MVoIPDownlinkObserver::KOpenComplete:
			if(aError == KErrNone)
				{
				TBool flag = ETrue;
				iDnFormat->FrameModeRequiredForErrorConcealment(flag);
				iDnFormat->SetFrameMode(ETrue);
				
				//now start streaming
				// FillBuffer will be called
				TInt err = iVoiceDnlink->Start();
				if(err != KErrNone)
					{
					CUtils::ShowMsg(_L("Start Dn err"),err);
					}
				}
			break;
			
		case MVoIPDownlinkObserver::KDownlinkError:
			
			break;
			
		case MVoIPDownlinkObserver::KDownlinkClosed:
			
			break;
			
		case MVoIPDownlinkObserver::KAudioDeviceChanged:
			
			break;
			
		default:
			break;
		}
	}


//===========================MVoIPUplinkObserver==============================
//
// Callback function, which indicate that record succeed,
// @param aBuffer is the voice data which can be sent to remote device
//
void CVoiceEngine::EmptyBuffer(const CVoIPAudioUplinkStream& aSrc,
        CVoIPDataBuffer* aBuffer)
	{
	//send aBuffer here
	
	}

void CVoiceEngine::Event(const CVoIPAudioUplinkStream& aSrc,
                       TInt aEventType,
                       TInt aError)
	{
	switch(aEventType)
		{
		case MVoIPDownlinkObserver::KOpenComplete:
			if(aError == KErrNone)
				{
				TBool flag = ETrue;
				iUpFormat->FrameModeRequiredForErrorConcealment(flag);
				iUpFormat->SetFrameMode(ETrue);
				
				//now start streaming
				// FillBuffer will be called
				TInt err = iVoiceUplink->Start();
				if(err != KErrNone)
					{
					CUtils::ShowMsg(_L("Start Dn err"),err);
					}
				}
			break;
			
		case MVoIPDownlinkObserver::KDownlinkError:
			
			break;
			
		case MVoIPDownlinkObserver::KDownlinkClosed:
			
			break;
			
		case MVoIPDownlinkObserver::KAudioDeviceChanged:
			
			break;
					
		default:
			break;
		}	
	}


//==========================MVoIPFormatObserver==========================
//
// do nothing here
//
void CVoiceEngine::Event(const CVoIPFormatIntfc& aSrc, TInt aEventType)
	{
	switch(aEventType)
		{
		case MVoIPFormatObserver::KSilenceBegin:
			
			break;
			
		case MVoIPFormatObserver::KSilenceUpdate:
			
			break;
			
		case MVoIPFormatObserver::KObserverEventMax:
			
			break;
			
		case MVoIPFormatObserver::KSilenceEnd:
			
			break;
			
		default:
			break;
		}	
	}
